#!/usr/bin/env python

from time import time
from json import loads
from json.decoder import JSONDecodeError
from common import loop, get_timestamp, randfloat, check_args
from log import out, err
from config import PROXY_RDS_KEY, PROXY_SW, BS_RDS_PERFIX
from ip import get_proxy_ip
from chrome import Chrome
from .base import Task as TaskBase

def bs_key(account):
    return '%s_%s' % (BS_RDS_PERFIX, account)

def jobs_key(account):
    return '%s_Jobs' % bs_key(account)

def job_running_key(account):
    return '%s_Running' % jobs_key(account)


class Task(TaskBase):

    def proxyServer(self):
        srv = self.rds.get(PROXY_RDS_KEY)
        out('ProxyServer Cache: %s' % srv)
        if srv:
            return srv
        #  proxy = {'code': 0, 'success': True, 'msg': '0', 'data': [{'port': 4246, 'ip': '121.8.28.235', 'isp': '电信', 'expire_time': '2020-01-10 17:58:47', 'city': '广东省广州市'}]}
        #  return '116.22.51.106:4226'
        proxy = get_proxy_ip(pro=440000)
        out('ProxyServer Get: %s' % proxy)
        proxy = proxy['data'][0]
        expire_time = get_timestamp(proxy['expire_time']) - int(time()) - 180
        out('PROXY Expore_time: ', expire_time)
        srv = "%s:%s" % (proxy['ip'], proxy['port'])
        self.rds.set(PROXY_RDS_KEY, srv, expire_time)
        return srv

    def get_browser_id(self):
        """
        获取浏览器标识
            account(支付宝账号)组合唯一标识
        """
        if not hasattr(self, 'browser_id'):
            self.browser_id = bs_key(self.account)
        return self.browser_id

    def get_jobs_key(self):
        """
        获取浏览器指令队列名
        """
        if not hasattr(self, 'jobs_key'):
            self.jobs_key = jobs_key(self.account)
        return self.jobs_key

    def get_jobs_running_key(self):
        """
        获取浏览器指令正在执行标识名
        """
        if not hasattr(self, 'jobs_running_key'):
            self.jobs_running_key = job_running_key(self.account)
        return self.jobs_running_key

    def shell(self, **kwargs):
        """
        获取指令执行
        """
        try:
            opt = self.center_options
            sec = int(randfloat(int(opt['RefreshStart']), int(opt['RefreshEnd'])))
            out('Get Browser Job Wait Sec: ', sec)
            cmd = self.rds.blpop(self.get_jobs_key(), sec)
            if cmd is None:
                cmd = {'cmdname': 'refresh'}
            else:
                cmd = loads(cmd[1])

            out('BS Shell Pop Command: ', cmd, type(cmd))

            cmdname = cmd.get('cmdname')
            m = __import__("bs.%s" % cmdname)
            #  out('BS Command Import: ', m)
            m = getattr(m, cmdname)
            #  out('BS Command Import Type: ', m)
            entry = getattr(m, 'Command')
            out('BS Command Import Entry: ', entry)

            self.rds.set(self.get_jobs_running_key(), self.cmdname)
            entry(self, cmd).start()
            self.rds.delete(self.get_jobs_running_key())
            out('BS Command Entry End: ', self.browser_id)

            if not self.rds.exists(self.get_browser_id()):
                out('Browser ID (%s) Not Exists Exit Shell' % self.get_browser_id())
                return True

        except JSONDecodeError:
            err('BS Command JSON Data Parse Error!', stack=True)
        except ImportError:
            err('未匹配的操作指令: %s' % cmdname, stack=True)
        except AttributeError as e:
            err("BS Command Not Found: %s" % e, stack=True)

        return False

    def create(self):
        """
        创建浏览器指令控制中心
        """
        #  创建浏览器
        self.chrome = Chrome()
        #  设置浏览器存在标识
        self.rds.set(self.browser_id, 1)
        #  获取浏览器工作队列名
        jobs_key = self.get_jobs_key()
        #  删除原有浏览器工作队列内容
        self.rds.delete(jobs_key)
        #  发送上线指令
        self.rds.rpush(jobs_key, self.task_params)

        loop(self.shell, delay=0.1)

        out('Browser %s Create End' % self.browser_id)

    def send(self):
        """
        发送浏览器操作指令
        """
        jobs_key = self.get_jobs_key()
        running_key = self.get_jobs_running_key()

        #  如果是充值指令优先处理
        if self.cmdname == 'deposit':
            return self.rds.lpush(jobs_key, self.task_params)

        #  指令正在执行或队列中有指令都不能继续执行本次指令
        if self.rds.exists(running_key) or self.rds.llen(jobs_key):
            return self.push(self.client, 'alipay', 'running')

        return self.rds.rpush(jobs_key, self.task_params)

    def push_status(self, state=None, call='alipay', op='online', **kwargs):
        """
        推送支付宝在线状态
        """
        if state is None:
            state = 1 if self.chrome.current_url.startswith(PORTAL_URL) else 0

        return self.push(self.client, 'alipay', op, merchant=self.merchant,
                         account=self.account, state=state, call=call, **kwargs)

    def quit(self, op=None, **kwargs):
        out('Browser Quit ID: ', self.get_browser_id())
        if hasattr(self, 'jobs_running_key') and self.jobs_running_key:
            self.rds.delete(self.jobs_running_key)
            self.jobs_running_key = None
        if hasattr(self, 'jobs_key') and self.jobs_key:
            self.rds.delete(self.jobs_key)
            self.jobs_key = None
        if hasattr(self, 'browser_id') and self.browser_id:
            self.rds.delete(self.browser_id)
            self.browser_id = None
        if hasattr(self, 'chrome') and self.chrome:
            try:
                self.chrome.quit()
            except:
                pass
            self.chrome = None
        if op is not None:
            return self.push_status(0, op=op, **kwargs)

    def run(self):
        """
        浏览器任务入口
        """
        #  检查浏览器基本参数是否为空
        if check_args(self.task_params, 'account', 'merchant', 'client', 'cmdname'):
            raise Exception('执行浏览器任务参数错误: %s' % self.task_params)

        #  判断支付宝绑定的浏览器是否存在, 存在发送指令, 不存在创建浏览器控制中心
        if self.rds.get(self.get_browser_id()):
            return self.send()
        if self.cmdname == 'online':
            return self.create()
        return self.push(self.client, 'alipay', 'unlogin')

